package easypal.brilliard.world.brilliards.communication.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import easypal.brilliard.world.brilliards.logic.BallColor;
import easypal.brilliard.world.brilliards.logic.HitRecord;

public class ProtocolUtil {
	public static String end = "\r\n";
	
	public static String makeJoin() {
		return "JOIN\r\n";
	}
	public static String makeWait() {
		return "WAIT\r\n";
	}
	public static String makeBegin() {
		return "BEGIN\r\n";
	}
	public static String makeExit() {
		return "EXIT\r\n";
	}
	public static String makeEnd(String winner) {
		return "END\r\nWinner:" + winner + "\r\n";
	}
	public static String makeNextTurn(BallColor target, String turn, int playerOneScore, int playerTwoScore, String whiteBall,
			List<BallColor> colorBallWhichNeedRecovered) {
		StringBuffer sb = new StringBuffer();
		sb.append("NEXT_TURN\r\n");
		sb.append("Target:" + target.toString() + "\r\n");
		sb.append("ScoreOne:" + playerOneScore + "\r\n");
		sb.append("ScoreTwo:" + playerTwoScore + "\r\n");
		sb.append("Turn:" + turn + "\r\n");
		
		sb.append("WhiteBall:" + whiteBall +"\r\n");
		sb.append("RecoverColorBall:");
		if (colorBallWhichNeedRecovered != null && colorBallWhichNeedRecovered.size() > 0) {
			String color = colorBallWhichNeedRecovered.get(0).toString();
			sb.append(color);
			
			for (int i=1; i < colorBallWhichNeedRecovered.size(); i++) {
				color = colorBallWhichNeedRecovered.get(i).toString();
				sb.append("," + color);
			}
		}
		sb.append("\r\n");
		
		return sb.toString();
	}
	
	public static String makeBallHit(int x, int y, int z,
			float dx, float dy, float dz, int f) {
		
		StringBuffer sb = new StringBuffer();
		sb.append("BALL_HIT\r\n");
		
		sb.append("Offset:");
		sb.append(x); sb.append(',');
		sb.append(y); sb.append(',');
		sb.append(z); sb.append("\r\n");
		
		sb.append("Direction:");
		sb.append(dx); sb.append(',');
		sb.append(dy); sb.append(',');
		sb.append(dz); sb.append("\r\n");
		
		sb.append("Force:");
		sb.append(f); sb.append("\r\n");
		
		return sb.toString();
	}
	
	public static String makeBallMotion(HitRecord hitRecord) {
		StringBuffer sb = new StringBuffer();
		List<BallColor> colors;
		
		sb.append("BALL_MOTION\r\n");
		
		sb.append("Touch:");
		colors = hitRecord.getTouchedBalls();
		if (colors.size() > 0) {
			sb.append(colors.get(0).toString());
			for (int i=1; i < colors.size(); i++) {
				sb.append("," + colors.get(i).toString());
			}
		}
		sb.append("\r\n");
		
		sb.append("Entered:");
		colors = hitRecord.getEnteredBalls();
		if (colors.size() > 0) {
			sb.append(colors.get(0).toString());
			for (int i=1; i < colors.size(); i++) {
				sb.append("," + colors.get(i).toString());
			}
		}
		sb.append("\r\n");
		
		sb.append("WhiteBall:");
		if (hitRecord.doesWhiteBallEnter()) {
			sb.append("Entered\r\n");
		} else {
			sb.append("NotEntered\r\n");
		}
		
		
		return sb.toString();
	}
	
	public static String makeBallTimeout() {
		return "BALL_TIMEOUT\r\n";
	}
	
	public static String makeOnlineRequest() {
		return "ONLINE_REQUEST\r\n";
	}
	public static String makeOnlineAck() {
		return "ONLINE_ACK\r\n";
	}
	
	public static String makeAnotherOffline() {
		return "ANOTHER_OFF\r\n";
	}
	public static String makeClientOffline() {
		return "CLIENT_OFF\r\n";
	}
	public static String makeServerOffline() {
		return "SERVER_OFF\r\n";
	}
	
	
	// parse message and store the key-value pair in the msg map;
	public static Map<String, String> parseMessage(String message) {
		Map<String, String> msg = new HashMap<String, String>();
		BufferedReader msgReader = new BufferedReader(new StringReader(message));
		
		try {
			String type = msgReader.readLine();
			msg.put("type", type);
			String line;
			while ( (line = msgReader.readLine()) != null) {
				StringTokenizer st = new StringTokenizer(line, ":");
				String key = st.nextToken();
				String value = "";
				if (st.hasMoreTokens()) value = st.nextToken();
				msg.put(key, value);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return msg;
	}
	
	public static List<String> parseCommaStringToList(String str) {
		List<String> list = new ArrayList<String>();
		StringTokenizer st = new StringTokenizer(str, ",");
		while (st.hasMoreTokens()) {
			list.add(st.nextToken());
		}
		return list;
	}
}
